/*
 * Copyright (c) 2007, 2008 Ulrich Hilger, http://dev.uhilger.de, all rights reserved.
 *
 * Published under the terms and conditions of the Apache License 2.0,
 * see http://www.apache.org/licenses/LICENSE-2.0
 */

package de.uhilger.lib.filesystem;


/**
 * Classes that represent a file system in the context of this  
 * package need to implement this interface.
 * 
 * @author Ulrich Hilger, http://dev.uhilger.de
 * @author Published under the terms and conditions of
 * the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>
 *
 * @version 2, 12.01.2008
 */

public interface FileSystem {
	
	/** url string for a local file system */
	public static final String LOCAL_FILE_SYSTEM = "local";
	
	/**
	 * add a listener to this file system
	 * @param listener  the listener to add
	 * @throws Throwable
	 */
	public void addFileSystemListener(FileSystemListener listener) throws Throwable;
	
	/**
	 * remove a listener from this file system
	 * @param listener  the listener to remove
	 * @throws Throwable
	 */
	public void removeFileSystemListener(FileSystemListener listener) throws Throwable;
	
	/**
	 * get the string that is used to separate file and folder names in path expressions 
	 * for the machine this file system refers to
	 * 
	 * @return the separator string
	 * @throws Throwable
	 */
	public String getFileSeparator() throws Throwable;
	
	/**
	 * get the root directories of this file system
	 * 
	 * @return  the root directories of this file system
	 * @throws Throwable
	 */
	public FileRef[] getRoots() throws Throwable;
	
	/**
	 * get the file that is directly on top of a given file in 
	 * the file hierarchy of this file system
	 * 
	 * @param file  the file to get the parent file for
	 * @return  the parent file
	 * @throws Throwable
	 */
	public FileRef getParentFile(FileRef file) throws Throwable;
	
	/**
	 * get the files that are contained in a given folder
	 * 
	 * @param folder  the directory to get the files for
	 * @return  the list of files contained in the given directory
	 * @throws Throwable
	 */
	public FileRef[] list(FileRef folder) throws Throwable;
	
	/**
	 * rename a file, i.e. change the name of a file but not its location
	 * 
	 * @param file  the file to rename
	 * @param newName  the new name; just the name, no path
	 * @throws Throwable
	 */
	public FileRef rename(FileRef file, String newName) throws Throwable;
	
	/**
	 * copy files to a given folder. 
	 * 
	 * @param filesToCopy  the files to copy
	 * @param toFolder  the directory to copy to
	 * @throws Throwable
	 */
	public boolean copy(FileRef[] filesToCopy, FileRef toFolder) throws Throwable;
	
	/**
	 * move one or more files to a given folder. 
	 * 
	 * @param filesToMove  the files to move
	 * @param toFolder the folder to move to
	 * @throws Throwable
	 */
	public boolean move(FileRef[] filesToMove, FileRef toFolder) throws Throwable;
	
	/**
	 * create a new folder
	 * 
	 * @param folder the folder to create
	 * @throws Throwable
	 */
	public boolean createFolder(FileRef folder) throws Throwable;
	
	/**
	 * delete one or more files
	 * @param filesToDelete  the list of files to delete
	 * @throws Throwable
	 */
	public boolean delete(FileRef[] filesToDelete) throws Throwable;
	
	/**
	 * pack the contents of a given folder into a new ZIP compressed archive
	 * @param folder  the folder to pack
	 * @param archive  the archive to create from the given files
	 * @throws Throwable
	 */
	public boolean pack(FileRef folder, FileRef archive) throws Throwable;
	
	/**
	 * extract a given ZIP archive to a given folder
	 * @param archive  the archive to extract
	 * @param toFolder  the folder to extract the contents of the archive to
	 * @throws Throwable
	 */
	public boolean extract(FileRef archive, FileRef toFolder) throws Throwable;
	
	/**
	 * determine whether or not a given file exists in this instance of file system
	 * @param file  the file to determine existence for
	 * @return  true if the given files exists in this instance of file system, false if not
	 * @throws Throwable
	 */
	public boolean fileExists(FileRef file) throws Throwable;
	
	/**
	 * determine the size of a folder in bytes
	 * @param folder  the folder to determine the size for
	 * @return  the size of the folder in bytes
	 * @throws Throwable
	 */
	public double getFolderSize(FileRef folder) throws Throwable;
	
	/**
	 * get the total size of a number of files
	 * @param files  the files to determine the total size for
	 * @return  the number of byte the given files have in total
	 * @throws Throwable
	 */
	public double getSize(FileRef[] files) throws Throwable;
	
	/**
	 * get the url string of the machine this file system is located
	 * @return  url string of machine this file system is located
	 * @throws Throwable
	 */
	public String getUrl() throws Throwable;
	
	/**
	 * write contents of a file using a byte array in memory as a buffer
	 * @param file  reference to the file to write
	 * @param contents  the contents to write to the referenced file
	 * @throws Throwable
	 */
	public boolean write(FileRef file, byte[] contents) throws Throwable;
	
	/**
	 * read contents of a file using a byte array in memory as a buffer
	 * @param file  reference to the file to read
	 * @return  the file contents
	 * @throws Throwable
	 */
	public byte[] read(FileRef file) throws Throwable;	
	
	/**
	 * import from a given file system to this file system
	 * @param sourceFiles  references to the files in the source file system that are to be imported
	 * @param importFolder  folder of this file system to import to
	 * @param sourceFs  the file system to import from
	 * @throws Throwable
	 */
	public void importFiles(FileRef[] sourceFiles, FileRef importFolder, FileSystem sourceFs) throws Throwable;
	
	/**
	 * export from this file system to a given target file system
	 * @param exportFiles  references to the files in this file system to export
	 * @param targetFolder  the folder of the target files system to export to
	 * @param targetFs  the file system to export to
	 * @throws Throwable
	 */
	public void exportFiles(FileRef[] exportFiles, FileRef targetFolder, FileSystem targetFs) throws Throwable;
	
	/**
	 * write data to a stream and store it in a given file
	 * @param fromFile the file to read data from
	 * @param toFile  the file to store data at
	 * @param out  the stream to write file contents to
	 * @throws Throwable
	 */
	//public boolean streamWrite(FileRef fromFile, FileRef toFile, OutputStream out) throws Throwable;
	
	/**
	 * read data from a stream store it in a file 
	 * @param fromFile the file to read data from
	 * @param toFile the file to store data in
	 * @param in the stream to read data from
	 * @throws Throwable
	 */
	//public boolean streamRead(FileRef fromFile, FileRef toFile, InputStream in) throws Throwable;
	
	/**
	 * indicate whether or not this file system implements writing file contents to a stream, 
	 * i.e. implements method streamWrite
	 * @return true when this file system supports writing to a stream, false if not
	 * @throws Throwable
	 */
	//public boolean implementsStreamWrite() throws Throwable;
	
	/**
	 * indicate whether or not this file system implements reading file contents from a stream, 
	 * i.e. implements method streamRead
	 * @return true when this file system supports reading from a stream, false if not
	 * @throws Throwable
	 */
	//public boolean implementsStreamRead() throws Throwable;
} 
